# _*_ coding:UTF-8 _*_

from DataCleaning import DataCleaning
import os
from  SimilarTrack import SimilarTrack
from ConnectTrack import ConnectTrack
import copy
import time
import math
import sys


class SameConsumer:
    '''
    该类主要用于判断几个顾客是否属于同一批顾客
    '''

    def __init__(self):
        pass

    def togetherLook(self, lookCar, threshold):
        '''
        判断顾客是否同时看同一辆车
        :param lookCar:（dist）看同一辆车的顾客的轨迹，这里的lookCar是main中的startAndLook{摄像头ID：车辆ID：顾客ID：顾客轨迹点}
        {摄像头ID:{车辆id：{顾客id：坐标（list）}}},由isStop方法得出
        :param threshold:（string）判断是否同时看车的阈值
        :return:{cameraID:{carID:[[一家人1],[一家人2],...]}}
        '''
        together = {}
        for camerakey in lookCar:
            aloneLookCar = lookCar[camerakey]  # 单个摄像头下的看车用户
            togetherConsumer = {}
            for carkey in aloneLookCar:  # 车
                consumerTrack = aloneLookCar[carkey]  # 看该车的所有顾客及轨迹
                together1 = []
                mark = []  # 用来存放已经遍历过的顾客的id
                for consumerkey in consumerTrack:  # 看车的顾客
                    if consumerkey not in mark:
                        mark.append(consumerkey)
                        togetherTemp = []
                        s1 = consumerTrack[consumerkey][0].split(",")[0]  # 顾客开始看车的帧数
                        e1 = consumerTrack[consumerkey][-1].split(",")[0]  # 顾客离开时的帧数

                        for secondConsumer in consumerTrack:  # 另外一个看车的顾客
                            if secondConsumer != consumerkey and secondConsumer not in mark:
                                s2 = consumerTrack[secondConsumer][0].split(",")[0]
                                e2 = consumerTrack[secondConsumer][-1].split(",")[0]
                                # 判断两个顾客是否同时看车(一起开始看车或者一起离开)
                                if abs(float(s1) - float(s2)) <= float(threshold) or abs(
                                                float(e1) - float(e2)) <= float(threshold):  # 逻辑上用and还是or呢？？？？？
                                    mark.append(secondConsumer)
                                    togetherTemp.append(consumerkey + "," + s1 + "," + e1)
                                    togetherTemp.append(secondConsumer + "," + s2 + "," + e2)

                        if len(togetherTemp) > 1:
                            together1.append(togetherTemp)
                if len(together1) > 0:
                    togetherConsumer[carkey] = together1
            together[camerakey] = togetherConsumer

        return together  # {cameraID:{carID:[[一家人1],[一家人2],...]}}

    def getTrackMat(self, track1, track2):
        '''
        把顾客的轨迹转换成轨迹矩阵
        :param track1: (list)轨迹1
        :param track2:（list）轨迹2
        :return:[[]]如[[0, 0], [1, 1], [2, 4], [2, 1], [2, 0],[3,3]]
        '''
        # t1=[]
        # t2=[]
        # for i in track1:
        #
        #     #考虑了矩形框的长和宽
        #     x=float(i[2])+float(i[4])/2.0
        #     y=float(i[3])+float(i[5])/2.0
        #     # # 不考虑了矩形框的长和宽
        #     # x = float(line[2])
        #     # y = float(line[3])
        #     tep = []
        #     tep.append(str(x))
        #     tep.append(str(y))
        #
        #     t1.append(tep)
        #
        # for i in track2:
        #
        #     x = float(i[2]) + float(i[4]) / 2
        #     y = float(i[3]) + float(i[5]) / 2
        #     tep=[]
        #     tep.append(str(x))
        #     tep.append(str(y))
        #
        #     t2.append(tep)
        t1 = map(lambda x: [x[2] + x[4] / 2.0, x[3] + x[5] / 2], track1)

        t2 = map(lambda x: [x[2] + x[4] / 2.0, x[3] + x[5] / 2], track2)
        return t1, t2

    def sameConsumer(self, togetherConsumer, trackFile, threshold, frame, similarity, allIdMap, trueIdMap, trackspath,
                     idMapInDoor):
        '''
        判断一群顾客是否是相似顾客
        :param togetherConsumer:{cameraID:{carID:[[一家人1],[一家人2],...]}}，一起看车的顾客
        :param trackFile:（DataFrame）存放了顾客进门轨迹的DataFrame（门口摄像头）
        :param threshold:（int）判断顾客一起进店的阈值
        :param frame:（int)对于顾客进门轨迹进行相似度判断时，截取轨迹的帧数
        :param similarity:（int）判断两条轨迹是否相似的阈值
        :param allIdMap:存储各个摄像头下的ID之间的映射关系,从原始文件中得到（dict）
        :param trueIdMap:存储各个摄像头下的ID之间的映射关系，通过轨迹拼接得到（dict）
        :param trackspath:(DataFrame)每所有摄像头对应的顾客轨迹的DataFrame{摄像头id：（string）路径}
        :param idMapInDoor:(dict)门口摄像头临时ID和真实Id之间的映射
        :return:{摄像头id：[[同一批顾客的id],[],.....]}
        '''
        dc = DataCleaning(self)
        st = SimilarTrack()
        ct = ConnectTrack(trackspath, allIdMap)
        dataCon = trackFile[trackFile.is_customer == 1]
        allTogether = {}

        # 判断是否一起进店
        tempIdMap = {}  # 存放拼接完成的ID映射关系
        for camerakey in togetherConsumer:  # 遍历每个摄像头
            dataAllCamer = trackspath[camerakey]
            dataAllCamer = dataAllCamer[dataAllCamer.is_customer == 1]
            togetherAlone = togetherConsumer[camerakey]
            # realId=allRealId[camerakey]
            idMap = allIdMap[camerakey]  # 单个摄像头下的id映射关系
            if trueIdMap.has_key(camerakey):
                aloneTrueIdMap = trueIdMap[camerakey]
            else:
                aloneTrueIdMap = {}
            ct.setIdMap(idMap)
            ct.setTrackFile(dataAllCamer)

            togetherComeIn = []
            aloneTempIdMap = {}
            for carkey in togetherAlone:  # 遍历每辆车
                togetherlook = togetherAlone[carkey]  # 同时看车的多组顾客
                for i in togetherlook:  # 对每一组顾客两两比较,判断是否同时进店
                    tag = False
                    # temp=copy.deepcopy(i)
                    tog = set()
                    for j in xrange(len(i) - 1):  # 前一个顾客
                        keys = idMapInDoor.keys()  # 对可以排序，保证遍历顺序是固定的
                        keys = map(int, keys)
                        keys.sort()

                        if idMap[i[j].split(",")[0]] != "":  # 原始文件中有映射关系
                            # 在这里假设门口的摄像头文件中一定存在真实id的轨迹
                            for key in keys:  # 根据真实Id推断出临时ID
                                if idMapInDoor[str(key)] == idMap[i[j].split(",")[0]]:
                                    tmp = key
                                    break
                                else:
                                    tmp = " "
                            if tmp == " ":
                                continue
                            data1 = dataCon[dataCon.tmp_id == float(tmp)].values
                            frame1 = data1[0][0]  # 进门的帧数

                        else:  # 原始文件中没有映射关系
                            if aloneTrueIdMap.has_key(i[j].split(",")[0]):  # 之前映射过
                                trueID = aloneTrueIdMap[i[j].split(",")[0]]
                                aloneTempIdMap[i[j]] = trueID

                                for key in keys:
                                    if idMapInDoor[str(key)] == trueID:  # 找到与真实ID相对应的临时ID
                                        tmp = key
                                        break
                                    else:
                                        tmp = " "
                                if tmp == " ":
                                    continue
                                data1 = dataCon[dataCon.tmp_id == float(tmp)].values  # 得到该顾客第一次出现时的帧数
                                frame1 = data1[0][0]

                            else:  # 之前没有映射过，现在开始映射
                                print time.time()
                                connectID = ct.connect(i[j].split(",")[0])[-1]
                                print time.time()
                                if idMap[connectID] != "":
                                    aloneTempIdMap[i[j]] = idMap[connectID]

                                    for key in keys:
                                        if idMapInDoor[str(key)] == aloneTempIdMap[i[j]]:
                                            tmp = key
                                            break
                                        else:
                                            tmp = " "
                                    if tmp == " ":
                                        continue
                                    data1 = dataCon[dataCon.tmp_id == float(tmp)].values
                                    frame1 = data1[0][0]
                                else:
                                    continue
                                    # else:#不存在映射关系
                                    #     temp[j]=" "#删除没有真实id的顾客
                                    #     continue

                        for k in xrange(j + 1, len(i)):  # 后一个顾客
                            if idMap[i[k].split(",")[0]] != "":  # 在原始文件中存在映射关系

                                for key in keys:
                                    if idMapInDoor[str(key)] == idMap[i[k].split(",")[0]]:
                                        tmp = key
                                        break
                                    else:
                                        tmp = " "
                                if tmp == " ":
                                    continue
                                data2 = dataCon[dataCon.tmp_id == float(tmp)].values
                                frame2 = data2[0][0]

                            else:  # 原始文件中不存在映射关系
                                if aloneTrueIdMap.has_key(i[k].split(",")[0]):  # 之前映射过
                                    trueID = aloneTrueIdMap[i[k].split(",")[0]]
                                    aloneTempIdMap[i[k]] = trueID

                                    for key in keys:

                                        if idMapInDoor[str(key)] == trueID:
                                            tmp = key
                                            break
                                        else:
                                            tmp = " "
                                    if tmp == " ":
                                        continue
                                    data2 = dataCon[dataCon.tmp_id == float(tmp)].values
                                    frame2 = data2[0][0]

                                else:  # 之前没有映射过，现在映射
                                    connectID = idMap[ct.connect(i[k].split(",")[0])[-1]]
                                    if connectID != "":

                                        for key in keys:
                                            if idMapInDoor[str(key)] == connectID:
                                                tmp = key
                                                break
                                            else:
                                                tmp = " "
                                        if tmp == " ":
                                            continue
                                        data2 = dataCon[dataCon.tmp_id == float(tmp)].values
                                        frame2 = data2[0][0]
                                    else:
                                        continue

                            if abs(float(frame1) - float(frame2)) <= threshold * 250:  # 判断顾客是否同时进店
                                # 如果是同时进门的，则判断他们进店时的方向是否一致
                                e1 = str(float(frame1) + frame)  # 进门结束的帧数
                                e2 = str(float(frame2) + frame)
                                t1 = dc.subTrack(data1, frame1, float(e1))
                                t2 = dc.subTrack(data2, frame2, float(e2))

                                track1, track2 = self.getTrackMat(t1, t2)  # 获取两个顾客的轨迹矩阵
                                if st.saleFollow(track1, track2) > similarity:
                                    tag = False
                                    continue
                                else:

                                    tog.add(i[j])
                                    tog.add(i[k])

                    if len(tog) > 0:
                        togetherComeIn.append(list(tog))
            tempIdMap[camerakey] = aloneTempIdMap
            allTogether[camerakey] = togetherComeIn

        # #减少计算的次数，如果看车的轨迹相似，则是一家人，这样的判断有必要吗？
        # #判断进店后的轨迹是否相似
        # realTogether={}
        # for camerakey in allTogether:
        #     togetherCome=allTogether[camerakey]
        #     idMap = allIdMap[camerakey]
        #
        #     im=tempIdMap[camerakey]#已经通过拼接计算出的顾客ID映射
        #
        #     allTogetherConsumer=[]
        #     for i in togetherCome:#每一组顾客两两比较
        #         tag=True
        #         tog=set()
        #         keys = idMapInDoor.keys()
        #         keys = map(int, keys)
        #         keys.sort()
        #
        #         for j in xrange(len(i)-1):#第一个顾客
        #
        #             if idMap[i[j].split(",")[0]] != "":#有映射关系
        #
        #                 for key in keys:
        #                     if idMapInDoor[str(key)] == idMap[i[j].split(",")[0]]:
        #                         tmp = key
        #                         break
        #                     else:
        #                         tmp = " "
        #                 if tmp == " ":
        #                     continue
        #                 data1 = dataCon[dataCon.tmp_id == int(tmp)]
        #                 data = data1.values
        #                 frame1 = data[0][0]#进门的帧数
        #
        #                 e1=str(float(frame1)+frame)#进门结束的帧数
        #
        #             else:#没有映射关系
        #                 if im.has_key(i[j]):
        #                     for key in keys:
        #                         if idMapInDoor[str(key)] == im[i[j]]:
        #                             tmp = key
        #                             break
        #                         else:
        #                             tmp = " "
        #                     if tmp == " ":
        #                         continue
        #                     data1=dataCon[dataCon.tmp_id == float(tmp)]
        #                     data = data1.values
        #                     frame1 = data[0][0]
        #
        #                     e1 = str(float(frame1) + frame)
        #
        #                 else:#其实，这里的else语句是多余的，因为在判断顾客是否同时进店的过程中，已经删除了没有真实ID的顾客
        #                     continue
        #             # track1 = sc.getTrackMat(dc.subTrack(path1, frame1, e1))
        #             for k in xrange(j+1,len(i)):#第二个顾客
        #                 keys = idMapInDoor.keys()
        #                 keys = map(int, keys)
        #                 keys.sort()
        #                 if idMap[i[k].split(",")[0]] != "":
        #                     for key in keys:
        #                         if idMapInDoor[str(key)] == idMap[i[k].split(",")[0]]:
        #                             tmp = key
        #                             break
        #                         else:
        #                             tmp = " "
        #                     if tmp == " ":
        #                         continue
        #                     data2=dataCon[dataCon.tmp_id ==float(tmp)]
        #                     data = data2.values
        #                     frame2 = data[0][0]
        #
        #                 else:
        #                     # if idMap[ct.connect(i[k].split(",")[0])[-1]]!="":
        #                     if im.has_key(i[k]):
        #                         for key in keys:
        #                             if idMapInDoor[str(key)] == im[i[k]]:
        #                                 tmp = key
        #                                 break
        #                             else:
        #                                 tmp = " "
        #                         if tmp == " ":
        #                             continue
        #                         data2 = dataCon[dataCon.tmp_id == float(tmp)]
        #                         data = data2.values
        #                         frame2 = data[0][0]
        #
        #                     else:
        #                         continue
        #
        #                 e2=str(float(frame2)+frame)
        #                 t1=dc.subTrack(data1, frame1, float(e1))
        #                 t2=dc.subTrack(data2,frame2,float(e2))
        #
        #                 track1,track2=self.getTrackMat(t1,t2)#获取两个顾客的轨迹矩阵
        #
        #                 if st.saleFollow(track1,track2)>similarity:
        #                     tag=False
        #                     continue
        #                 else:
        #
        #                     tog.add(i[j])
        #                     tog.add(i[k])
        #             # if not tag:
        #             #     break
        #         if len(tog)>0:
        #             allTogetherConsumer.append(list(tog))
        #     realTogether[camerakey]=allTogetherConsumer#不同摄像头下的一家人
        # 有没有必要对togetherConsumer中的数据去重（一家人看了多辆车），看后期数据的情况，去重的方法在下面

        return allTogether, tempIdMap  # 原始ID

    def choiceMaster(self, togetherConsumer, allIdMap, tempIdMap, allFellows):
        '''
        根据销售的跟随程度，在同一批顾客中选出家长，销售跟随最近的为master
        :param togetherConsumer:（list）同一批顾客{摄像头id:[[同一批顾客的id],[],.....]}
        :param allIdMap:(dict)原始文件中的顾客id映射
        :param tempIdMap:(dict)拼接后的顾客Id映射
        :param allFellows:（float）之前已经计算过的被销售跟随的顾客的映射
        :return:{摄像头:{家长：跟随顾客（list）}},######这种设计可能会有问题，key有可能会重复
        '''

        allMaster = {}
        for camerakey in togetherConsumer:
            aloneTogetherConsumer = togetherConsumer[camerakey]
            masterOfConsumer = {}
            idMap = allIdMap[camerakey]
            tIdMap = tempIdMap[camerakey]
            if allFellows.has_key(camerakey):
                fellows = allFellows[camerakey]
            else:
                fellows = {}
            for consumerList in aloneTogetherConsumer:
                # 先为同一批顾客中的每个人找一个与他轨迹相似的销售，理论上，同一批顾客的跟随销售是同一个，最后根据情况调整策略
                consumerAndSale = {}
                minDis = 9999999.0
                # 从之前的计算结果中查找距离
                for consumer in consumerList:
                    id = consumer.split(",")[0]
                    mastertmp = None
                    if not idMap[id]:  # !=""，在原始文件中就有真实id对应
                        if fellows.has_key(idMap[id]):
                            dis = fellows[idMap[id]].split(",")[1]
                            if minDis >= dis:
                                minDis = dis
                                mastertmp = consumer


                    elif tIdMap.has_key(id):  # 通过关联，找到真实ID
                        if fellows.has_key(tIdMap[id]):
                            dis = fellows[tIdMap[id]].split(",")[1]
                            if minDis >= dis:
                                minDis = dis
                                mastertmp = consumer

                master = None
                if mastertmp != None:  # 如果销售有跟随
                    # l = sorted(consumerAndSale.items(), key=lambda d: d[1])#tuple
                    master = mastertmp.split(",")[0]
                else:  # 如果销售没有跟随，则在组群中的第一个顾客为master
                    master = consumerList[0].split(",")[0]
                if not masterOfConsumer.has_key(master):
                    masterOfConsumer[master] = consumerList
                else:
                    masterOfConsumer[master].extend(consumerList)  # 合并同一个master的两家人
            allMaster[camerakey] = masterOfConsumer

        return allMaster

    def mergeMaster(self, allMaster, allIdMap, allRealId, trackspath):
        '''
        合并不同摄像头下的一家人
        :param allMaster:多个摄像头下的一家人{摄像头:{家长：跟随顾客（list）}}
        :param allIdMap:存储各个摄像头下的ID之间的映射关系（dict）
        :param allRealId:各个摄像头下的原始ID（dict）
        :param trackspath:(dict)每所有摄像头对应的顾客轨迹的存放路径{摄像头id：（string）路径}
        :return:{master:[一家人]}
        '''
        pass

    def distinct(self, togetherConsumer):
        '''
        去重，因为一家人有可能看了多辆车，则togetherConsumer中的数据可能是[["1,23,45","2,25,45"],["1,78,100","2,70,97"],......]
        :param togetherConsumer: [[同一批顾客的id],[],.....]
        :return: [[同一批顾客的id],[],.....](无重复）
        '''

        temp = {}
        for consumerlist in togetherConsumer:
            consumerlist.sort()
            key = ""
            for con in consumerlist:
                key += con.split(",")[0]
            temp[key] = consumerlist

        togetherConsumerUniq = []
        for k in temp:
            togetherConsumerUniq.append(temp[k])

        return togetherConsumerUniq

        # 用同时进店和进店后轨迹相似来判断顾客是否是集体

    def togetherCome(self, startInTime):
        '''
        判断顾客是否同时进店（门口没有框）
        :param startInTime: 顾客进店的时间戳
        :return: （list）一起进店的顾客
        '''
        togetherComeConsumer = []
        mask = []
        key = startInTime.keys()
        for i in range(0, len(key) - 1):
            if key[i] in mask:
                continue
            temp = []
            temp.append(key[i])
            mask.append(key[i])
            for j in range(i + 1, len(key)):
                if key[j] in mask:
                    continue

                if abs(int(startInTime[key[i]]) - int(startInTime[key[j]])) <= 10:  # 前后相差10s
                    temp.append(key[j])
                    mask.append(key[j])
                else:  # 从第一个不是同时进店的人开始，后面的所有人都肯定不是同时进店的
                    break
            if len(temp) > 1:
                togetherComeConsumer.append(temp)

        return togetherComeConsumer

    def togetherCome2(self, startInTime, doorArea, dataInDoor, dc, period):
        '''
        判断顾客是否同时进店（门口有框）
        :param startInTime: 顾客进店的时间戳
        :param doorArea:(list)门口位置的参数
        :param dataInDoor:（DataFrame）门口顾客的轨迹数据
        :param dc:DataCleaning对象
        :param period:判定同时进店的时间间隔
        :return: （list）一起进店的顾客
        '''
        togetherComeConsumer = []
        mask = []
        keys = startInTime.keys()
        key = sorted(keys)
        # key=keys.sort()

        data = dataInDoor[dataInDoor.is_customer == 1]  # 顾客的轨迹数据
        for i in range(0, len(key) - 1):
            if key[i] in mask:
                continue
            temp = []
            temp.append(key[i])
            mask.append(key[i])
            data1 = data[data.tmp_id == float(key[i])]
            consumer1Coord = data1[0:1].values[0][2:6]
            consumer1Area = dc.overlopArea(doorArea, consumer1Coord)  # 顾客第一帧数据到门口的距离
            if consumer1Area <= 0.95:
                continue

            for j in range(i + 1, len(key)):
                if key[j] in mask:
                    continue

                data2 = data[data.tmp_id == float(key[j])]
                consumer2Coord = data2[0:1].values[0][2:6]
                consumer2Area = dc.overlopArea(doorArea, consumer2Coord)  # 顾客第一帧数据到门口的距离
                if consumer2Area <= 0.95:
                    continue

                if abs(float(startInTime[key[i]]) - float(startInTime[key[j]])) <= period:  # 前后相差10s
                    temp.append(key[j])
                    mask.append(key[j])
                if abs(float(startInTime[key[i]]) - float(
                        startInTime[key[j]])) > period:  # 从第一个不是同时进店的人开始，后面的所有人都肯定不是同时进店的
                    break
            if len(temp) > 1:
                togetherComeConsumer.append(temp)
            elif (len(data[data.tmp_id == float(temp[0])]) > 26):
                print temp[0]

        return togetherComeConsumer


    def togetherCome3(self, startInTime, doorArea, dataInDoor, dc, period, timeThreshold):
        '''
        判断顾客是否同时进店（门口有框）
        :param startInTime: 顾客进店的时间戳
        :param doorArea:(list)门口位置的参数
        :param dataInDoor:（DataFrame）门口顾客的轨迹数据
        :param dc:DataCleaning对象
        :param period:判定同时进店的时间间隔
        :param timeThreshold:单顾客最小轨迹时长
        :return: （list）一起进店的顾客
        '''
        togetherComeConsumer = []
        mask = []
        keys = startInTime.keys()
        key = sorted(keys)
        # key=keys.sort()

        data = dataInDoor[dataInDoor.is_customer == 1]  # 顾客的轨迹数据
        singleCount = 0
        for i in range(0, len(key) - 1):
            if key[i] in mask:
                continue
            temp = []
            temp.append(key[i])
            mask.append(key[i])
            data1 = data[data.tmp_id == float(key[i])]
            consumer1Coord = data1[0:1].values[0][2:6]

            x1, y1, width1, height1 = [0,0,0,0]
            x2, y2, width2, height2 = [0,0,0,0]
            x3, y3, width3, height3 = [0,0,0,0]
            x1, y1, width1, height1 = doorArea
            x2, y2, width2, height2 = consumer1Coord
            x3, y3, width3, height3 = data1[data1.shape[0]-1:data1.shape[0]].values[0][2:6]

            if not ((float(y3) > float(y2)) and ((float(y3) + float(height3)) > (float(y1) + float(height1)/2))):
                continue
            #jianhao
            if (not ((float(x3) < 80) or ((float(x3) +float(width3))> 1000) or ((float(y3)+float(height3)) > 560))):
                continue

            consumer1Area = dc.overlopArea(doorArea, consumer1Coord)  # 顾客第一帧数据到门口的距离
            if consumer1Area <= 0.95:
                continue

            for j in range(i + 1, len(key)):
                if key[j] in mask:
                    continue

                data2 = data[data.tmp_id == float(key[j])]
                consumer2Coord = data2[0:1].values[0][2:6]
                consumer2Area = dc.overlopArea(doorArea, consumer2Coord)  # 顾客第一帧数据到门口的距离
                if consumer2Area <= 0.95:
                    continue

                if abs(float(startInTime[key[i]]) - float(startInTime[key[j]])) <= period:  # 前后相差10s
                    temp.append(key[j])
                    mask.append(key[j])
                if abs(float(startInTime[key[i]]) - float(
                        startInTime[key[j]])) > period:  # 从第一个不是同时进店的人开始，后面的所有人都肯定不是同时进店的
                    break
            if len(temp) > 1:
                togetherComeConsumer.append(temp)
                print("family batch time: " + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(startInTime[key[i]]))))
            elif(len(data[data.tmp_id == float(temp[0])]) > timeThreshold):
    	        singleCount += 1
                print("single batch time: " + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(startInTime[key[i]]))))
        return togetherComeConsumer, singleCount

    #cxhui add saleServiceInDoor1 to get how many saleservice in door camera
    def saleServiceInDoor1(self, startInTime,doorArea,dataInDoor,dc,frame,similarThd):
        '''
        找出所有销售跟踪轨迹里，其起始时间附近的所有顾客轨迹，轨迹点最近距离判决为迎宾
        轨迹时间相差10s最近距离，否则不计算
        '''
        mask = []
        saleServiceNum=0
        st = SimilarTrack()
        keys = startInTime.keys() #直接用了跟踪里面的起始时间
        key=sorted(keys)
        #print(type(key[1]))
        #print(key)
        custData=dataInDoor[dataInDoor.is_customer == 1]#顾客的轨迹数据
        saleData=dataInDoor[dataInDoor.is_customer == 2]#销售的轨迹数据
        if 0 == len(saleData) or 0 == len(custData):
            print("No salor or customer")
            return 0

        #print(len(saleData.tmp_id))
        #print(len(custData.tmp_id))

        count = 0;

        custIDlst = list(set(custData.tmp_id))
        for oneCust in custIDlst:

            data1 = custData[custData.tmp_id == float(oneCust)]
            consumer2Coord = data1[0:1].values[0][2:6]
            consumer2Area = dc.overlopArea(doorArea, consumer2Coord)  # 顾客第一帧数据到门口的距离
            if consumer2Area <= 0.95:
                continue

            try:
                custTime = float(startInTime[str(oneCust)])                
            except:
                continue
        
            datac = data1.values
            frame1 = datac[0][0] # 获取顾客轨迹的起始帧数
            e1 = float(frame1) + frame * 250

            #print(list(set(saleData.tmp_id)))
            for oneSale in list(set(saleData.tmp_id)):
                #print(type(oneSale))
                #print(oneSale)
                #sys.exit()
                try:
                    saleTime = float(startInTime[str(oneSale)])
                    count += 1
                except:                    
                    continue
                if abs(saleTime - custTime) > 10.0:  # 前后相差大于10s的继续轮询下个
                    continue

                data2 = saleData[saleData.tmp_id == float(oneSale)]

                datas = data2.values
                frame2=datas[0][0]
                e2 = float(frame2) + frame * 250
                t1 = dc.subTrack(data1, frame1, e1)
                t2 = dc.subTrack(data2, frame2, e2)
                track1, track2 = self.getTrackMat(t1, t2)
                print("3:")
                #如果相似度过门限判决为这个销售轨迹是跟踪的并推出顾客的轮询
                if st.saleFollow(track1, track2) > similarThd:
                    saleServiceNum += 1
                    break      
        return saleServiceNum

    def findAllConsumerInDoor1(self, startInTime, doorArea, doorName, dataInDoor, dc, period, frame, similarity,
                               timeThreshold):
        """
        :param startInTime: 顾客进店的时间戳
        :param doorArea:门口位置的参数
        :param dataInDoor:（DataFrame）门口顾客的轨迹数据
        :param dc:DataCleaning对象
        :param period:判定同时进店的时间间隔
        :param frame:（int)对于顾客进门轨迹进行相似度判断时，截取轨迹的帧数
        :param similarity:（int）判断两条轨迹是否相似的阈值
        :param timeThreshold: 单顾客最小轨迹时长
        :return: 进店的顾客总人数，进店总批次数
        """

        togetherCome, singleCount = self.togetherCome3(startInTime, doorArea[doorName[0]].split(","), dataInDoor, dc,
                                                       period, timeThreshold)
        familly = self.sameConsumerInDoor1(togetherCome, dataInDoor, frame, similarity, {}, doorArea)
        famillySum, famillyNum = self.getFamillyInfo(familly)

        print "single batch: " + str(singleCount)
        print "familly batch: " + str(famillyNum)

        return singleCount + famillySum, singleCount + famillyNum

    def mapReal(self, togetherComeConsumer, idMap):
        '''
        对一起进门顾客进行临时ID和真实ID之间的映射
        :param togetherComeConsumer:（list）一起进门的顾客（临时id）
        :param idMap:（dict）门口临时id和真实id之间的映射
        :return:（list）同时进门的顾客（真实ID）
        '''
        realIdTogetherConsumer = []
        for together in togetherComeConsumer:
            temp = set()
            for i in together:
                if idMap[i] != "":
                    temp.add(idMap[i])
            tmp = list(temp)
            if len(tmp) >= 2:  # 一群人至少是两个人
                realIdTogetherConsumer.append(tmp)

        return realIdTogetherConsumer

    def sameConsumerInDoor(self, togetherConsumer, trackFile, frame, similarity, idMapInDoor):
        '''
        判断一群顾客是否是相似顾客(门口没有框，真实id)
        :param togetherConsumer:（list）[[一家人1],[一家人2],...]，一起进门的顾客
        :param trackFile:（string）存放了顾客进门轨迹的文件夹路径（门口摄像头）
        :param frame:（int)对于顾客进门轨迹进行相似度判断时，截取轨迹的帧数
        :param similarity:（int）判断两条轨迹是否相似的阈值
        :param idMapInDoor:(dict)门口摄像头临时ID和真实Id之间的映射
        :return:（list）[[同一批顾客的id],[],.....]
        '''
        # 判断进店后的轨迹是否相似
        dc = DataCleaning(self)
        st = SimilarTrack()
        dataCon = trackFile[trackFile.is_customer == 1]  # 门口的轨迹数据

        keys = idMapInDoor.keys()
        keys = map(int, keys)
        keys.sort()
        realTogether = []
        for together in togetherConsumer:

            for i in xrange(len(together) - 1):
                tag = True
                tog = set()

                for key in keys:
                    if idMapInDoor[str(key)] == together[i]:  # 找到和真实id相对应的临时id
                        tmp = key
                        break
                    else:
                        tmp = " "
                if tmp == " ":
                    continue

                data1 = dataCon[dataCon.tmp_id == float(tmp)]
                data = data1.values
                frame1 = data[0][0]  # 获取轨迹的起始帧数
                e1 = float(frame1) + frame * 250

                for k in xrange(i + 1, len(together)):

                    for key in keys:
                        if idMapInDoor[str(key)] == together[k]:
                            tmp = key
                            break
                        else:
                            tmp = " "
                    if tmp == " ":
                        continue

                    data2 = dataCon[dataCon.tmp_id == float(tmp)]
                    dataT = data2.values
                    # path2 = os.path.join(trackFile, "%s%s" % (tmp, ".txt"))
                    # f2 = open(path2, 'r')
                    # line2 = f2.readline()
                    # frame2 = line2.strip().split(",")[0]
                    frame2 = dataT[0][0]

                    e2 = float(frame2) + frame * 250
                    t1 = dc.subTrack(data1, frame1, e1)
                    t2 = dc.subTrack(data2, frame2, e2)
                    track1, track2 = self.getTrackMat(t1, t2)

                    if st.saleFollow(track1, track2) > similarity:
                        tag = False
                        continue
                    else:
                        tog.add(together[i])
                        tog.add(together[k])
            if len(tog) > 0:
                realTogether.append(list(tog))

        # 有没有必要对togetherConsumer中的数据去重（一家人看了多辆车），看后期数据的情况，去重的方法在下面

        return realTogether  # 原始ID

    def sameConsumerInDoor1(self, togetherConsumer, trackFile, frame, similarity, idMapInDoor, doorArea):
        '''
        判断一群顾客是否是相似顾客(门口有框)
        :param togetherConsumer:（list）[[一家人1],[一家人2],...]，一起进门的顾客（临时ID）
        :param trackFile:（string）存放了顾客进门轨迹的文件夹路径（门口摄像头）
        :param frame:（int)对于顾客进门轨迹进行相似度判断时，截取轨迹的帧数
        :param similarity:（int）判断两条轨迹是否相似的阈值
        :param idMapInDoor:(dict)门口摄像头临时ID和真实Id之间的映射
        :return:（list）[[同一批顾客的id],[],.....]
        '''

        # 判断进店后的轨迹是否相似
        k = doorArea.keys()
        doorCoord = doorArea[k[0]]
        doorCoord = doorCoord.split(",")
        y = float(doorCoord[1]) + float(doorCoord[3])
        dc = DataCleaning(self)
        st = SimilarTrack()
        dataCon = trackFile[trackFile.is_customer == 1]  # 门口的轨迹数据

        realTogether = []
        for together in togetherConsumer:

            tog = set()
            for i in xrange(len(together) - 1):

                startInDoor1 = 0
                data1 = dataCon[dataCon.tmp_id == float(together[i])]
                data = data1.values
                # frame1 = data[0][0] # 获取轨迹的起始帧数
                # x1=data[0][2]
                # y1=data[0][3]
                # # frame1 = line1.strip().split(",")[0]  # 获取轨迹的起始帧数
                #
                # # for line1 in f1.readlines():
                # #     frame1=line1.strip().split(",")[1]
                # #     break
                # e1 = float(frame1) + frame * 250

                # 方案一：找到共同进门顾客的前m帧数据，用这m帧的数据来判断顾客进门后行走的方向是否一致
                frame1 = data[0][0]
                for j in range(len(data)):  # 找到顾客距离门最近的位置
                    yTmp = float(data[j][3]) + float(data[j][5])
                    if y - yTmp < 120.0:  # 找到顾客距离门口最近的帧数，从这一帧开始取数据
                        frame1 = data[j][0]
                        startInDoor1 += 1
                        # print frame1
                        break
                # endFrame1=data[-1][0]#取出最后一帧图片
                # s1=endFrame1-frame*250

                for k in xrange(i + 1, len(together)):
                    startInDoor2 = 0
                    data2 = dataCon[dataCon.tmp_id == float(together[k])]
                    data = data2.values
                    frame2 = data[0][0]
                    for m in range(len(data)):
                        yTmp = float(data[m][3]) + float(data[m][5])
                        if y - yTmp <= 120.0:
                            startInDoor2 += 1
                            frame2 = data[m][0]
                            break

                    # 根据不同的策略来选取阈值
                    if startInDoor2 + startInDoor1 == 2:
                        e1 = float(frame1) + frame * 250 * 2 / 3
                        e2 = float(frame2) + frame * 250 * 2 / 3
                        t1 = dc.subTrack(data1, frame1, e1)
                        t2 = dc.subTrack(data2, frame2, e2)
                        track1, track2 = self.getTrackMat(t1, t2)
                        s = st.togetherGo(track1, track2)
                        s = s * 3 / 2
                    else:
                        e1 = float(frame1) + frame * 250
                        e2 = float(frame2) + frame * 250
                        t1 = dc.subTrack(data1, frame1, e1)
                        t2 = dc.subTrack(data2, frame2, e2)
                        track1, track2 = self.getTrackMat(t1, t2)
                        s = st.togetherGo(track1, track2)

                    # 方案二：对于两两同时进门的顾客从后出现的一个顾客开始的帧数开始取数据
                    #
                    # if frame2<frame1:
                    #     who=1
                    # else:
                    #     who=2
                    # if who==1:
                    #     sFrame1=max(frame1,frame2)#向前退5帧
                    #     sFrame2=sFrame1-5*250
                    #     eFrame1=sFrame1+frame * 250*2/3
                    #     eFrame2 = sFrame2 + frame * 250 * 2 / 3
                    # else:
                    #     sFrame2 = max(frame1, frame2)  # 向前退5帧
                    #     sFrame1 = sFrame2 - 5 * 250
                    #     eFrame1 = sFrame1 + frame * 250 * 2 / 3
                    #     eFrame2 = sFrame2 + frame * 250 * 2 / 3
                    #
                    # t1 = dc.subTrack(data1, sFrame1, eFrame1)
                    # t2 = dc.subTrack(data2, sFrame2, eFrame2)
                    # track1, track2 = self.getTrackMat(t1, t2)
                    # if len(track1)==0 or len(track2)==0:
                    #     continue
                    # s = st.togetherGo(track1, track2)
                    # s = s * 3 / 2

                    if s > similarity:
                        continue
                    else:
                        tog.add(together[i])
                        tog.add(together[k])

            if len(tog) > 0:
                realTogether.append(list(tog))
            else:
                tog.add(together[0])
                realTogether.append(list(tog))

        # 有没有必要对togetherConsumer中的数据去重（一家人看了多辆车），看后期数据的情况，去重的方法在下面
        # allTogether=[]
        # for  together  in realTogether:
        #     tag = False
        #     together=map(str,together)
        #     for i in together:#一家人中至少要有一个人有真实ID
        #         l=idMapInDoor[i]
        #         if idMapInDoor[i] !="" :
        #             tag=True
        #             break
        #     if tag:
        #         allTogether.append(together)

        return realTogether  # 原始ID

    def choiceMasterInDoor(self, togetherConsumer, follows):
        '''
        在同一批顾客中选出家长
        :param togetherConsumer:（list）同一批顾客{摄像头id:[[同一批顾客的id],[],.....]]
        :param follows:（float）之前已经计算过的被销售跟随的顾客的映射
        :return:{摄像头:{家长：跟随顾客（list）}},######这种设计可能会有问题，key有可能会重复
        '''
        allMaster = {}
        for together in togetherConsumer:
            minDis = 9999999.0
            for i in together:
                if follows.has_key(i):
                    dis = follows[i]
                    if minDis >= dis:
                        minDis = dis
                        mastertmp = i
                    else:
                        mastertmp = i
                else:
                    mastertmp = i
            allMaster[mastertmp] = together

        return allMaster

    def getFamillyRatio(self, lookcarNum, familly):
        '''
        把人群按比例划分到看车/上车的顾客中
        :param lookcarNum:看车/上车的顾客数量
        :param familly:人群数量
        :return:（dict）每个车被人群的数量
        '''
        famillyLen = len(familly)
        sum = 0
        # 统计看车/上车的总人数
        for carkey in lookcarNum:
            sum += int(lookcarNum[carkey])
        famillyNum = {}
        for carkey in lookcarNum:
            if sum == 0:  # sum不能为0
                famillyNum[carkey] = 0
                continue
            famillyNum[carkey] = int((float(lookcarNum[carkey]) / float(sum)) * famillyLen)

        return famillyNum

    def getFamillyInfo(self, familly):
        '''
        获取人群总数及人群总人数
        :param familly:（list）人群
        :return:（int）人群总数及人群总人数
        '''
        famillyNum = len(familly)  # 人群总数
        famillySum = 0  # 人群总人数
        for batch in familly:
            famillySum += len(batch)

        return famillySum, famillyNum


if __name__ == '__main__':

    print "----------共同看车-----------"
    lookcar = {"car1": ["1,9,15", "2,9,16", "4,22,27", "5,22,26", "34,200,240"]}
    sc = SameConsumer()
    togetherConsmer = sc.togetherLook(lookcar, "1")
    for key in togetherConsmer:
        templist = togetherConsmer[key]
        print key
        print  templist

    print "----------一家人-----------"
    afamily = sc.sameConsumer(togetherConsmer, u"F:\项目实施部工作文件夹\上汽项目\\test_SameConsumer\\", 1, 10, 10000)
    print afamily

    print "----------master-----------"
    master = sc.choiceMaster(afamily, u"F:\项目实施部工作文件夹\上汽项目\\test_SameConsumer\sale\\",
                             u"F:\项目实施部工作文件夹\上汽项目\\test_SameConsumer\\", 10000.0)
    print  master
